package com.anolesoft.yr.mbus.contm.service.impl;

import com.anolesoft.yr.mbus.cont.entity.ItemType;
import com.anolesoft.yr.mbus.cont.entity.PageType;
import com.anolesoft.yr.mbus.contm.dao.ContmStyleItemDao;
import com.anolesoft.yr.mbus.contm.dao.ContmStyleMainDao;
import com.anolesoft.yr.mbus.contm.entity.ContmStyleItem;
import com.anolesoft.yr.mbus.contm.entity.ContmStyleItemExample;
import com.anolesoft.yr.mbus.contm.entity.ContmStyleMain;
import com.anolesoft.yr.mbus.contm.service.StyleInsertService;
import com.anolesoft.yr.mbus.contm.util.DocUtil;
import com.anolesoft.yr.mbus.contm.util.FileUtil;
import com.anolesoft.yr.mbus.contm.util.StringUtil;
import com.anolesoft.yr.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Element;
import org.dom4j.Node;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.security.Security;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StyleInsertServiceImpl implements StyleInsertService {
    @Autowired
    private ContmStyleMainDao contmStyleMainDao;
    @Autowired
    private ContmStyleItemDao contmStyleItemDao;
    @Override
    public File getZipFile(String path) {
        return null;
    }
    @Override
    public void docStyleInsertMain(String filePath, String styleName, String remark){
        File docxFile = new File(filePath);
        //KeyMap对比模板内内容将赋予模板类型
        Map<String,String> keyMap = new HashMap<>();
        keyMap.put("合同名称",ItemType.FIRST_PAGE_TITLE);
        keyMap.put("首页内容",ItemType.FIRST_PAGE_CONTENT);
        keyMap.put("说明页标题",ItemType.SECOND_PAGE_TITLE);
        keyMap.put("副页编号列表",ItemType.SECOND_PAGE_LIST);
        keyMap.put("副页内容",ItemType.SECOND_PAGE_CONTENT);
        keyMap.put("合同订立页标题",ItemType.MAKE_PAGE_TITLE);
        keyMap.put("合同订立副标题",ItemType.MAKE_PAGE_SECOND_TITLE);
        keyMap.put("合同订立内容",ItemType.MAKE_PAGE_CONTENT);
        keyMap.put("内容页一级标题",ItemType.CONTENT_PAGE_TITLE);
        keyMap.put("内容页二级标题",ItemType.CONTENT_PAGE_TITLE);
        keyMap.put("内容页三级标题",ItemType.CONTENT_PAGE_TITLE);
        keyMap.put("内容页四级标题",ItemType.CONTENT_PAGE_TITLE);
        keyMap.put("内容页一级标题内容",ItemType.CONTENT_PAGE_CONTENT);
        keyMap.put("内容页二级标题内容",ItemType.CONTENT_PAGE_CONTENT);
        keyMap.put("内容页三级标题内容",ItemType.CONTENT_PAGE_CONTENT);
        keyMap.put("内容页四级标题内容",ItemType.CONTENT_PAGE_CONTENT);
        keyMap.put("内容页内容列表",ItemType.CONTENT_PAGE_LIST);
        keyMap.put("合同签订标题",ItemType.SIGN_PAGE_TITLE);
        keyMap.put("合同签订双方签章",ItemType.SIGN_PAGE_CONTENT);
        keyMap.put("附件页标题",ItemType.LAST_PAGE_TITLE);
        keyMap.put("附件页一级标题内容",ItemType.LAST_PAGE_CONTENT);
        keyMap.put("附件页二级标题内容",ItemType.LAST_PAGE_CONTENT);
        keyMap.put("附件页三级标题内容",ItemType.LAST_PAGE_CONTENT);
        keyMap.put("附件页内容一级标题",ItemType.LAST_PAGE_TITLE_LIST);
        keyMap.put("附件页内容二级标题",ItemType.LAST_PAGE_TITLE_LIST);
        keyMap.put("附件页内容三级标题",ItemType.LAST_PAGE_TITLE_LIST);
        keyMap.put("附件内容列表",ItemType.LAST_PAGE_CONTENT_LIST);

        Map<String,String> pageKeyMap = new HashMap<>();
        pageKeyMap.put("合同名称", PageType.FIRST_PAGE);
        pageKeyMap.put("首页内容", PageType.FIRST_PAGE);
        pageKeyMap.put("说明页标题", PageType.SECOND_PAGE);
        pageKeyMap.put("附页编号列表",PageType.SECOND_PAGE);
        pageKeyMap.put("副页内容",PageType.SECOND_PAGE);
        pageKeyMap.put("合同订立页标题",PageType.MAKE_PAGE);
        pageKeyMap.put("合同订立副标题",PageType.MAKE_PAGE);
        pageKeyMap.put("合同订立内容",PageType.MAKE_PAGE);
        pageKeyMap.put("内容页一级标题",PageType.CONTENT_PAGE);
        pageKeyMap.put("内容页二级标题",PageType.CONTENT_PAGE);
        pageKeyMap.put("内容页三级标题",PageType.CONTENT_PAGE);
        pageKeyMap.put("内容页四级标题",PageType.CONTENT_PAGE);
        pageKeyMap.put("内容页一级标题内容",PageType.CONTENT_PAGE);
        pageKeyMap.put("内容页二级标题内容",PageType.CONTENT_PAGE);
        pageKeyMap.put("内容页三级标题内容",PageType.CONTENT_PAGE);
        pageKeyMap.put("内容页四级标题内容",PageType.CONTENT_PAGE);
        pageKeyMap.put("内容页内容列表",PageType.CONTENT_PAGE);
        pageKeyMap.put("合同签订标题",PageType.SIGN_PAGE);
        pageKeyMap.put("合同签订双方签章",PageType.SIGN_PAGE);
        pageKeyMap.put("附件页标题",PageType.LAST_PAGE);
        pageKeyMap.put("附件页一级标题内容",PageType.LAST_PAGE);
        pageKeyMap.put("附件页二级标题内容",PageType.LAST_PAGE);
        pageKeyMap.put("附件页三级标题内容",PageType.LAST_PAGE);
        pageKeyMap.put("附件页内容一级标题",PageType.LAST_PAGE);
        pageKeyMap.put("附件页内容二级标题",PageType.LAST_PAGE);
        pageKeyMap.put("附件页内容三级标题",PageType.LAST_PAGE);
        pageKeyMap.put("附件页内容",PageType.LAST_PAGE);
        pageKeyMap.put("附件内容列表",PageType.LAST_PAGE);
        pageKeyMap.put("附件页普通内容",PageType.LAST_PAGE);

        Map<String,Integer> titleLvlKeyMap = new HashMap<>();
        titleLvlKeyMap.put("合同名称",0);
        titleLvlKeyMap.put("首页内容",0);
        titleLvlKeyMap.put("说明页标题",0);
        titleLvlKeyMap.put("附页编号列表",0);
        titleLvlKeyMap.put("副页内容",0);
        titleLvlKeyMap.put("合同订立页标题",0);
        titleLvlKeyMap.put("合同订立副标题",0);
        titleLvlKeyMap.put("合同订立内容",0);
        titleLvlKeyMap.put("内容页一级标题",1);
        titleLvlKeyMap.put("内容页二级标题",2);
        titleLvlKeyMap.put("内容页三级标题",3);
        titleLvlKeyMap.put("内容页四级标题",4);
        titleLvlKeyMap.put("内容页一级标题内容",1);
        titleLvlKeyMap.put("内容页二级标题内容",2);
        titleLvlKeyMap.put("内容页三级标题内容",3);
        titleLvlKeyMap.put("内容页四级标题内容",4);
        titleLvlKeyMap.put("内容页内容列表",0);
        titleLvlKeyMap.put("合同签订标题",0);
        titleLvlKeyMap.put("合同签订双方签章",0);
        titleLvlKeyMap.put("附件页标题",0);
        titleLvlKeyMap.put("附件页一级标题内容",1);
        titleLvlKeyMap.put("附件页二级标题内容",2);
        titleLvlKeyMap.put("附件页三级标题内容",3);
        titleLvlKeyMap.put("附件页内容一级标题",1);
        titleLvlKeyMap.put("附件页内容二级标题",2);
        titleLvlKeyMap.put("附件页内容三级标题",3);
        titleLvlKeyMap.put("附件内容列表",0);
        titleLvlKeyMap.put("附件页内容",1);
        titleLvlKeyMap.put("附件页普通内容",0);
        String stringMianObj = StringUtil.generateRundom32String();
        String empUid = SecurityUtils.getLoginUser().getEmpUid();
        ContmStyleMain contmStyleMain = ContmStyleMain.builder().objuid(stringMianObj).cTime(new Date()).styleName(styleName).stylePath(filePath).cUserUid(empUid).delFlag(Byte.parseByte("0")).remark(remark).build();
        contmStyleMainDao.insert(contmStyleMain);

        try {
            //获取zip文件
            File zipFile = FileUtil.changeSuffix(docxFile,"zip");
            //获取文件内document.XML文件进行读取操作
            Map<String, Element> xmlFile = DocUtil.getXmlFile(zipFile, "word/document.xml");
            Map<String, Element> numberFile = DocUtil.getXmlFile(zipFile, "word/numbering.xml");
            Element numberElement =  numberFile.get("word/numbering.xml");
            Element documentElement = xmlFile.get("word/document.xml").element("body");
            //段落list
            List<Element> pList = documentElement.elements("p");
            //表格list
            List <Element>tableList = documentElement.elements("tbl");
            //获取一个key的集合方便循环
            List<String> keyMapList = keyMap.keySet().stream().collect(Collectors.toList());
            //循环获取每一个p节点，将内容取出来与key比较并进行类型匹配
            pList.forEach(a->{
                String code = a.asXML();
                String pText = DocUtil.getPText(a).replace("（","(");
                if(pText.length()>0) {
                    pText+="(";
                    String keyWord = pText.substring(0, pText.indexOf("("));
                    keyMapList.forEach(b -> {
                        //建立待存储对象
                        if (b.equals(keyWord)) {
                            if (keyMap.get(b).equals(ItemType.CONTENT_PAGE_LIST)){
                                Element temp = a.element("pPr").element("numPr");
                                String numId = temp.element("numId").attributeValue("val");
                                Element numElement = (Element)numberElement.selectSingleNode("//w:num[@w:numId='" + numId + "']");
                                String abstractNumId = numElement.element("abstractNumId").attributeValue("val");
                                Element abstractNumIdElement = (Element)numberElement.selectSingleNode("//w:abstractNum[@w:abstractNumId='" + abstractNumId + "']");

                                ContmStyleItem num = ContmStyleItem.builder().objuid(StringUtil.generateRundom32String()).code(numElement.asXML()).contmStyleUid(stringMianObj)
                                .pageType(PageType.NUMBER_PAGE)
                                .itemType(ItemType.CONTENT_PAGE_LIST_NUM).lvl(new Byte("0")).build();
                                contmStyleItemDao.insert(num);
                                ContmStyleItem abNum = ContmStyleItem.builder().objuid(StringUtil.generateRundom32String()).code(abstractNumIdElement.asXML()).contmStyleUid(stringMianObj)
                                        .pageType(PageType.NUMBER_PAGE)
                                        .itemType(ItemType.CONTENT_PAGE_LIST_ABSTRACT_NUM).lvl(new Byte("0")).build();
                                contmStyleItemDao.insert(abNum);

                            }else if(keyMap.get(b).equals(ItemType.LAST_PAGE_CONTENT_LIST)) {
                                Element temp = a.element("pPr").element("numPr");
                                String numId = temp.element("numId").attributeValue("val");
                                Element numElement = (Element) numberElement.selectSingleNode("//w:num[@w:numId='" + numId + "']");
                                String abstractNumId = numElement.element("abstractNumId").attributeValue("val");
                                Element abstractNumIdElement = (Element) numberElement.selectSingleNode("//w:abstractNum[@w:abstractNumId='" + abstractNumId + "']");

                                ContmStyleItem num = ContmStyleItem.builder().objuid(StringUtil.generateRundom32String()).code(numElement.asXML()).contmStyleUid(stringMianObj)
                                        .pageType(PageType.NUMBER_PAGE)
                                        .itemType(ItemType.LAST_PAGE_LIST_NUM).lvl(new Byte("0")).build();
                                contmStyleItemDao.insert(num);
                                ContmStyleItem abNum = ContmStyleItem.builder().objuid(StringUtil.generateRundom32String()).code(abstractNumIdElement.asXML()).contmStyleUid(stringMianObj)
                                        .pageType(PageType.NUMBER_PAGE)
                                        .itemType(ItemType.LAST_PAGE_LIST_ABSTRACT_NUM).lvl(new Byte("0")).build();
                                contmStyleItemDao.insert(abNum);
                            }

                            ContmStyleItem contmStyleItem = ContmStyleItem.builder().objuid(StringUtil.generateRundom32String()).code(code).contmStyleUid(stringMianObj).build();
                            contmStyleItem.setPageType(pageKeyMap.get(b));
                            contmStyleItem.setItemType(keyMap.get(b));
                            contmStyleItem.setLvl(new Byte(titleLvlKeyMap.get(b)+""));
                            contmStyleItemDao.insert(contmStyleItem);
                        }

                    });
                }
            });

            Element sectPr = documentElement.element("sectPr");
            ContmStyleItem contmStyleItem = ContmStyleItem.builder().pageType(PageType.SYSTEM_PAGE).lvl(new Byte("0")).itemType(ItemType.PAGE_PROPERTY).objuid(StringUtil.generateRundom32String()).code(sectPr.asXML()).contmStyleUid(stringMianObj).build();
            ContmStyleItem numberItem = ContmStyleItem.builder().pageType(PageType.NUMBER_PAGE).lvl(new Byte("0")).itemType(ItemType.NUMBER_PAGE).objuid(StringUtil.generateRundom32String()).code(numberElement.asXML()).contmStyleUid(stringMianObj).build();
            contmStyleItemDao.insert(contmStyleItem);
            contmStyleItemDao.insert(numberItem);
            if (tableList.size()>0){
                Element element = tableList.get(0);
                ContmStyleItem tbl = ContmStyleItem.builder().objuid(StringUtil.generateRundom32String()).code(element.asXML()).contmStyleUid(stringMianObj).build();
                tbl.setPageType(PageType.TABLE);
                tbl.setItemType(ItemType.TABLE);
                tbl.setLvl(new Byte("0"));
                contmStyleItemDao.insert(tbl);
            }else{
                throw new RuntimeException("导入的样式文件中缺少表格属性的样式！");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("导入时解析出错");
        }finally {
        }
    }

    @Override
    public void docStyleMainEdit(String styleName, String remark, String objuid) {
        String empUid = SecurityUtils.getLoginUser().getEmpUid();
        String stringMianObj = objuid;
        ContmStyleMain contmStyleMain = ContmStyleMain.builder().objuid(stringMianObj).mTime(new Date()).styleName(styleName).mUserUid(empUid).delFlag(Byte.parseByte("0")).remark(remark).build();
        contmStyleMainDao.updateByPrimaryKey(contmStyleMain);
    }
}
